﻿using System.Xml.Linq;
using IcicleFramework.Entities;
using Microsoft.Xna.Framework;

namespace IcicleFramework.Components.Actions.ActionEffects
{
    public abstract class BaseActionEffect : IActionEffect
    {
        #region Properties

        public bool Paused { get; protected set; }

        public IActionComponent Parent { get; set; }

        public IActionComponent Target { get; set; }

        public IGameObject ParentGameObject { get { return Parent.Parent; } }

        public string Name { get; set; }

        public bool Permanent { get; protected set; }

        #endregion


        #region Events

        public event OnAttachHandler OnDetach;

        public event OnAttachHandler OnAttach;

        #endregion


        #region Constructors

        protected BaseActionEffect() {}

        protected BaseActionEffect(IActionEffect old)
        {
            this.Permanent = old.Permanent;
            this.Name = old.Name;
        }

        #endregion


        #region Initialization

        public virtual void Initialize() { }

        public virtual void PostInitialize() { }

        #endregion


        #region Attaching and Detaching

        public virtual void Attached(IActionComponent target) { }

        protected virtual void PerformDetach()
        {
            if (OnDetach != null)
            {
                OnDetach(this, Target);
            }

            RemoveEffect();
        }

        public virtual bool Detach(bool forceDetach = false)
        {
            //Don't perform the Detach operation if we're a permanent action effect and we're not forced to leave.
            if (Permanent && !forceDetach) 
                return false;

            PerformDetach();
            return true;
        }

        #endregion


        #region Applying and Removing Effects

        protected abstract void ApplyEffect();

        protected abstract void RemoveEffect();

        #endregion


        public virtual void Update(GameTime gameTime) { }


        #region Pausing

        public virtual void Pause()
        {
            Paused = true;
        }

        public virtual void Resume()
        {
            Paused = false;
        }

        #endregion

        public abstract IActionEffect DeepClone();

        public virtual void Deserialize(XElement element)
        {
            bool permanent = false;
            XElement permElement = element.Element("permanent");

            if (permElement != null)
            {
                bool.TryParse(permElement.Value, out permanent);
            }
            Permanent = permanent;
        }
    }
}
